package com.lu.test.aop;

import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

// 开启aop spring提供了三种方式
// 1. 向容器注入 BeanNameAutoProxyCreator 但是这个需要指定 被代理的 beans 和 代理逻辑+切入点 （Advisor）
// 2. 向容器注入 DefaultAdvisorAutoProxyCreator 这个是BeanNameAutoProxyCreator的升级 不需要指定 。
// 		这个是会自动寻找需要被代理的对象和切入点 （Advisor） 不包含注解形式
// 3. 开启EnableAspectJAutoProxy 注解 。当然这个本身也是向容器注入了一个bean AnnotationAwareAspectJAutoProxyCreator
// 	  	这个是通过注解方式 + Advisor

//@EnableAspectJAutoProxy
// exposeProxy  true：ThreadLocal暴露Aop代理对象。解决事务失效
// proxyTargetClass true:走cglib代理
@EnableAspectJAutoProxy(proxyTargetClass = false, exposeProxy = false)

//1. @Before对应的是AspectJMethodBeforeAdvice，直接实现MethodBeforeAdvice，在进行动态代理时会把AspectJMethodBeforeAdvice转成MethodBeforeAdviceInterceptor，也就转变成了MethodBeforeAdviceInterceptor
//  a. 先执行advice对应的方法
//  b. 再执行MethodInvocation的proceed()，会执行下一个Interceptor，如果没有下一个Interceptor了，会执行target对应的方法
//2. @After对应的是AspectJAfterAdvice，直接实现了MethodInterceptor
//  a. 先执行MethodInvocation的proceed()，会执行下一个Interceptor，如果没有下一个Interceptor了，会执行target对应的方法
//  b. 再执行advice对应的方法
//3. @Around对应的是AspectJAroundAdvice，直接实现了MethodInterceptor
//  a. 直接执行advice对应的方法
//4. @AfterThrowing对应的是AspectJAfterThrowingAdvice，直接实现了MethodInterceptor
//  a. 先执行MethodInvocation的proceed()，会执行下一个Interceptor，如果没有下一个Interceptor了，会执行target对应的方法
//  b. 如果上面抛了Throwable，那么则会执行advice对应的方法
//5. @AfterReturning对应的是AspectJAfterReturningAdvice，实现了AfterReturningAdvice，在进行动态代理时会把AspectJAfterReturningAdvice转成AfterReturningAdviceInterceptor，也就转变成了MethodInterceptor
//  a. 先执行MethodInvocation的proceed()，会执行下一个Interceptor，如果没有下一个Interceptor了，会执行target对应的方法
//  b. 执行上面的方法后得到最终的方法的返回值
//  c. 再执行Advice对应的方法
@Configuration
public class AopConfig {

	@Bean
	public LogAspect logAspect() {
		return new LogAspect();
	}

	@Bean
	public IStudentService studentService() {
		return new StudentService();
	}

	@Bean
	public Service1 service1() {
		return new Service1();
	}


//	@Bean
//	// BeanNameAutoProxyCreator 是一个 beanPostProcessor
//	// 需要指定 被代理的 beans 和 代理逻辑+切入点
//	public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
//		BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
//		beanNameAutoProxyCreator.setBeanNames("userService");
//		beanNameAutoProxyCreator.setInterceptorNames("myAdvisor");
//		return beanNameAutoProxyCreator;
//	}
//
//	@Bean
//	// DefaultAdvisorAutoProxyCreator 是一个 beanPostProcessor
//	// DefaultAdvisorAutoProxyCreator 比 BeanNameAutoProxyCreator 更高级，是不需要指定。因为他会自己去找
//	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
//		DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
//		return defaultAdvisorAutoProxyCreator;
//	}
}
